⚙️

Advanced Content
This page contains advanced concepts and/or JavaScript.

This page collects all tutorials for extending Snap's boundaries and documents preliminary steps in doing so.

Prelimnary

These tutorials suppose you have a basic knowledge of JavaScript and that NodeJS is installed on your machine. You'll also need an editor. Your PC surely ships with a basic text editor (eg Notepad for Windows) but it surely doesn't support advanced features like an IDE can have. For this, I recommend VSCode. These tutorials will use it, but any other editor should work.

Check you have everything set up by opening a command shell (eg cmd.exe on Windows) and typing node --version and enter. You should see something like v14.0.0. Also try npm --version. I see v6.14.9, you should see something like that.

Create a new folder somewhere and open it in Visual Studio Code, in the "Terminal" window type npm init -y (and enter). Create a new file index.js and paste the following:

const https = require('https'); // ①
const {readFileSync: rf} = require('fs'); // ②

const options = {
  key: rf('key.pem'),
  cert: rf('cert.pem')
}; // ③

const server = https.createServer( // ④
  options,
  async (req, res) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.writeHead(200);
    res.end(`Sample!`);
  } // ⑤
);

server.listen(+(process.argv[2] || 8080), () => console.log('Listening!')); // ⑥

If you have worked in Node before, you can see we are reading two files key.pem and cert.pem that don't exist! This is because Snap! enforces HTTPS, that in short requires sites to have a "certificate" to prove they are not being hacked. As we are going to open a local server through which we communicate with Snap!, we are also needed to use HTTPS. For this, we will generate a self-signed certificate, that we must tell the browser to trust. Install OpenSSL and run these commands in the Terminal:

openssl genrsa -out key.pem
openssl req -new -key key.pem -out csr.pem
openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
rm csr.pem

Now run node index and when you see a line that says Listening!, open your favorite browser (the one you'll use with Snap!) and visit https://localhost:8080 (the https:// part is important). You'll see a notice about the browser not trusting the certificate, but click on "Continue to site" or "Trust" or similar. If you don't see such a button, try clicking on Advanced Options. If you still can't find it, ask for help in the talk page!

After these steps, you should see Sample! in your browser. If that's not the case, try double-checking your code, pressing Ctrl+C in your terminal to kill the Node process and restart it (node index).

Now try opening Snap!. Get the url [snap.berkeley.edu] :: sensing reporter block and change it into url [https://localhost:8080] :: sensing reporter. Click on it and this should be your result: .

Modularization

Now it's time we add support for modularization. Edit the function inside createServer to be:

async (req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*')
  if (req.url == '/') {
    res.writeHead(200);
    res.end(`~~ operational ~~`);
    return;
  }
  try {
    const v = req.url.split(/\//).slice(1);
    const module = v[0];
    const command = v[1];
    const args = v.slice(2);

    res.writeHead(200);
    res.end(await (require(`./${module}`)[command])(...args));
  } catch (e) {
     res.writeHead(400);
     res.end(e);
  }
}

Now we have support for modularization! Create another file sample.js and paste the following:

exports.main = async () => {
  return 'Main sample!'
}

exports.operate = async (op, a, b) => {
  if (op == '+') return (+a) + (+b);
  return NaN;
}

Close and reopen the server (Ctrl-C, node input) and this time open https://localhost:8080/sample/main. You should see Main sample!. Now navigate to https://localhost:8080/sample/operate/+/10/5. If you see 15, then you're all set!

Next steps (pre-build modules)

(TBA!)